 
  

 






<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html>

<!-- Mirrored from www.javapractices.com/topic/TopicAction.do?Id=34 by HTTrack Website Copier/3.x [XR&CO'2010], Sun, 12 Jun 2011 17:28:07 GMT -->
<!-- Added by HTTrack --><meta http-equiv="content-type" content="text/html;charset=UTF-8"><!-- /Added by HTTrack -->
<head>
 <title>
  Java Practices -> Lazy initialization
 </title>
 <link rel="stylesheet" type="text/css" href="../stylesheet8.css" media="all">
 
 <link rel="shortcut icon" href='../images/favicon.ico' type="image/vnd.microsoft.icon">
 <meta name="description" content="Concise presentations of java programming practices, tasks, and conventions, amply illustrated with syntax highlighted code examples.">
 
 <meta name='keywords' content='field,optimisation,optimization,lazy,java,java programming,java practices,java idiom,java style,java design patterns,java coding conventions,'>
 
 
</head>
 
<body>


<div class='menu-bar'>
 
  <a href='../home/HomeAction.html' title='Table of Contents'>Home</a> |
  <a href='../vote/VoteSummaryAction-2.html' title='View Poll Results'>Poll</a> |
   
  <A href='../feedback/FeedbackAction451f-2.html?Operation=Show' title='Send Your Feedback'>Wiki</a> |
  <b><a href='../source/SourceAction-2.html' title='Grab Source Code'>Source Code</a></b><IMG class='no-margin' SRC="../images/goldstar.gif" ALT=""> |

  <a href='http://www.web4j.com/Java_Web_Application_Framework_Overview.jsp?From=1' title='Free Download - Java Web Application Framework'><b>WEB4J</b></a> |
  
  <a href='http://www.date4j.net/' title='Replacement for java.util.Date'><b>DATE4J</b></a> |

   <a href='../references/ReferencesAction-2.html' title='References'>Links</a>
   
  <form action='http://www.javapractices.com/search/SearchAction.do' method='get' class='search-form'>
   <input type='text' name='SearchTerms' value="" size=12 maxlength=50 class='search'>
   <input type='submit' value="Search">
  </form>
 
</div>

<P>



  

 






<p class="display-messages">

 

 

</p>


<div class="main-layout">
 
   

 




<div class='page-title'>Lazy initialization</div>

<div class='main-body'>
 
<br>Lazy initialization is a performance optimization. 
It's used when data is deemed to be 'expensive' for some reason.
For example:
<ul>
<li>if the <tt>hashCode</tt> value for an object might not actually be needed by its caller, 
always calculating the <tt>hashCode</tt> for all instances of the object may be felt to be unnecessary. 
<li>since accessing a file system or network is relatively slow, such operations 
should be put off until they are absolutely required.
</ul>

Lazy initialization has two objectives :
<ul>
 <li><i>delay</i> an expensive operation until it's absolutely necessary
 <li><i>store</i> the result of that expensive operation, such that you won't need 
 to repeat it again
</ul>

<p>As usual, the size of any performance gain, if any, is highly dependent on the
problem, and in many cases may not be significant. As with any optimization,
this technique should be used only if there is a clear and significant
benefit. 

<P>To avoid a <tt>NullPointerException</tt>, a class must 
<a href='TopicAction3d35-2.html'>self-encapsulate</a> fields that have lazy initialization.
That is, a class cannot refer <em>directly</em> to such fields, but must access them through a method.

<P>The <a href="TopicAction78db-2.html">hashCode</a> method of an 
<a href="TopicActiond838-2.html">immutable</a> Model Object is a common candidate for lazy initialization. 


<p><b>Example 1</b>
<P>In this example, there are two fields with lazy initialization - <tt>fHashCode</tt> and <tt>fAwards</tt>.
<br>
<PRE>

<span class='keyword'>import</span> java.util.*;

<span class='keyword'>public</span> <span class='keyword'>final</span> <span class='keyword'>class</span> Athlete {

  <span class='keyword'>public</span> Athlete(<span class='keyword'>int</span> aId){
    <span class='comment'>//a toy implementation:
</span>    fId = aId;
    fName = <span class='literal'>"Roger Bannister"</span>;
    <span class='comment'>//fAwards is not set here!
</span>  }

  <span class='comment'>//..elided
</span>
  <span class='comment'>/**
   Lazy initialization is used here; this assumes that awards
   may not always be of interest to the caller,
   and that for some reason it is particularly expensive to
   fetch the List of Awards.
  */</span>
  <span class='keyword'>public</span> List getAwards(){
    <span class='keyword'>if</span> ( fAwards == <span class='keyword'>null</span> ) {
      <span class='comment'>//the fAwards field has not yet been populated
</span>      <span class='comment'>//Here is a toy implementation
</span>      List&lt;String&gt; awards = <span class='keyword'>new</span> ArrayList&lt;String&gt;();
      awards.add( <span class='literal'>"Gold Medal 2006"</span> );
      awards.add( <span class='literal'>"Bronze Medal 1998"</span> );
      fAwards = awards;
    }
    <span class='keyword'>return</span> fAwards;
  }

  <span class='comment'>/**
   This style applies only if the object is immutable.
   
   Another alternative is to calculate the hashCode once, when the 
   object is initially constructed (again, applies only when object is 
   immutable).
  */</span>
  <span class='keyword'>@Override</span> <span class='keyword'>public</span> <span class='keyword'>int</span> hashCode(){
    <span class='keyword'>if</span> ( fHashCode == <span class='literal'>0</span> ) {
     fHashCode = HashCodeUtil.SEED;
     fHashCode = HashCodeUtil.hash(fHashCode, fId);
     fHashCode = HashCodeUtil.hash(fHashCode, fName);
     <span class='comment'>//self-encapusulated: fAwards is not referenced directly, 
</span>     <span class='comment'>//since it may be null:
</span>     fHashCode = HashCodeUtil.hash(fHashCode, getAwards());
    }
    <span class='keyword'>return</span> fHashCode;
  }

  <span class='comment'>// PRIVATE //
</span>  <span class='keyword'>private</span> <span class='keyword'>int</span> fId;
  <span class='keyword'>private</span> String fName;
  <span class='keyword'>private</span> List&lt;String&gt; fAwards;
  <span class='keyword'>private</span> <span class='keyword'>int</span> fHashCode;
} 
</PRE>
<br>

<p><b>Example 2</b>
<P>Here, the look up of the printers available to a desktop PC is treated as an expensive operation.
<br>
<PRE>

<span class='keyword'>import</span> java.util.Arrays;
<span class='keyword'>import</span> java.util.List;

<span class='keyword'>import</span> javax.print.DocFlavor;
<span class='keyword'>import</span> javax.print.PrintService;
<span class='keyword'>import</span> javax.print.PrintServiceLookup;
<span class='keyword'>import</span> javax.print.attribute.HashPrintRequestAttributeSet;
<span class='keyword'>import</span> javax.print.attribute.PrintRequestAttributeSet;
<span class='keyword'>import</span> javax.print.attribute.standard.OrientationRequested;
<span class='keyword'>import</span> javax.print.attribute.standard.Sides;

<span class='comment'>/** Printing services available to a desktop client. */</span>
<span class='keyword'>public</span> <span class='keyword'>final</span> <span class='keyword'>class</span> Printers {

  <span class='comment'>/** Print some plain text (perhaps internally converted to PDF). */</span>
  <span class='keyword'>void</span> printSomething(String aText, PrintService aPrinter) {
    <span class='comment'>//...elided
</span>  }

  <span class='comment'>/** Return the list of printers that can print PDFs (double-sided, portrait).*/</span>
  List&lt;PrintService&gt; listAvailablePrinters(){
    <span class='keyword'>if</span>(fAvailablePrinters == <span class='keyword'>null</span>){
      <span class='comment'>//double-sided, portrait, for PDF files.
</span>      PrintRequestAttributeSet attrs = <span class='keyword'>new</span> HashPrintRequestAttributeSet();
      attrs.add(Sides.DUPLEX);
      attrs.add(OrientationRequested.PORTRAIT);
      <span class='comment'>//Expensive operation! This can take several seconds in some environments:
</span>      fAvailablePrinters = Arrays.asList(
        PrintServiceLookup.lookupPrintServices(DocFlavor.INPUT_STREAM.PDF, attrs)
      );
    }
    <span class='keyword'>return</span> fAvailablePrinters;
  }
  
  <span class='comment'>// PRIVATE
</span>  
  <span class='comment'>/**
   Looked up once, the first time it's needed, and then stored using a 
   static reference. If it was a non-static reference, then 
   the list of available printers would not be looked up just once, 
   but perhaps many times (once per 'Printers' object, and not once per 
   loaded 'Printers' class).
   
   Self-encapsulate :
   If this class's implementation needs to reference this item, it must do 
   so indirectly, by calling listAvailablePrinters().  
  */</span>
  <span class='keyword'>private</span> <span class='keyword'>static</span> List&lt;PrintService&gt; fAvailablePrinters;
  
}  
</PRE>
<br>

<br><b>Example 3</b>
<p>Lazy initialization is particularly useful for GUIs which take a long
time to construct.
<p>There are several policies for GUI construction which a design may follow:
<ul>
<li>
always build - construct the window many times, whenever it is demanded,
and do not cache the result.</li>

<li>
first-request build - construct the window once, when first requested.
Cache the result for any further requests, should they occur.</li>

<li>
background build - construct the window once, in a low priority worker
thread, when the system is initialized. Cache the result for any requests,
should they occur.</li>
</ul>
Here is an example of the first-request style, in which the <tt>fEditor</tt>
field has lazy initialization (see the <tt>actionPerformed</tt> method).
<br>
<PRE>

<span class='keyword'>package</span> hirondelle.stocks.preferences;

<span class='keyword'>import</span> java.awt.event.*;
<span class='keyword'>import</span> javax.swing.*;
<span class='keyword'>import</span> java.util.*;
<span class='keyword'>import</span> java.util.logging.*;

<span class='keyword'>import</span> hirondelle.stocks.util.Args;
<span class='keyword'>import</span> hirondelle.stocks.util.ui.StandardEditor;
<span class='keyword'>import</span> hirondelle.stocks.util.ui.UiUtil;
<span class='keyword'>import</span> hirondelle.stocks.preferences.PreferencesEditor;
<span class='keyword'>import</span> hirondelle.stocks.util.Util;

<span class='comment'>/**
* Present dialog to allow update of user preferences.
*
* &lt;P&gt;Related preferences are grouped together and placed in 
* a single pane of a &lt;tt&gt;JTabbedPane&lt;/tt&gt;, which corresponds to an 
* implementation of {@link PreferencesEditor}. Values are pre-populated with 
* current values for preferences.
*
*&lt;P&gt;Most preferences have default values. If so, a  
* &lt;tt&gt;Restore Defaults&lt;/tt&gt; button is provided for that set of related 
* preferences.
*
*&lt;P&gt;Preferences are not changed until the &lt;tt&gt;OK&lt;/tt&gt; button is pressed. 
* Exception: the logging preferences take effect immediately, without the need 
* for hitting &lt;tt&gt;OK&lt;/tt&gt;.
*/</span>
<span class='keyword'>public</span> <span class='keyword'>final</span> <span class='keyword'>class</span> EditUserPreferencesAction <span class='keyword'>extends</span> AbstractAction {

  <span class='comment'>/**
  * Constructor.
  *  
  * @param aFrame parent window to which this dialog is attached.
  * @param aPrefEditors contains implementations of {@link PreferencesEditor}, 
  * each of which is placed in a pane of a &lt;tt&gt;JTabbedPane&lt;/tt&gt;.
  */</span>
  <span class='keyword'>public</span> EditUserPreferencesAction (JFrame aFrame, List&lt;PreferencesEditor&gt; aPrefEditors) {
    <span class='keyword'>super</span>(<span class='literal'>"Preferences..."</span>, UiUtil.getEmptyIcon()); 
    Args.checkForNull(aFrame);
    Args.checkForNull(aPrefEditors);
    fFrame = aFrame;
    putValue(SHORT_DESCRIPTION, <span class='literal'>"Update user preferences"</span>);
    putValue(LONG_DESCRIPTION, <span class='literal'>"Allows user input of preferences."</span>);
    putValue(MNEMONIC_KEY, <span class='keyword'>new</span> Integer(KeyEvent.VK_P) );    
    fPrefEditors = aPrefEditors;
  }

  <span class='comment'>/** Display the user preferences dialog.  */</span>
  <span class='keyword'>public</span> <span class='keyword'>void</span> actionPerformed(ActionEvent event) {
    fLogger.info(<span class='literal'>"Showing user preferences dialog."</span>);
    <span class='comment'>//lazy construction: fEditor is created only once, when this action 
</span>    <span class='comment'>//is explicitly invoked
</span>    <span class='keyword'>if</span> ( fEditor == <span class='keyword'>null</span> ) {
      fEditor = <span class='keyword'>new</span> Editor(<span class='literal'>"Edit Preferences"</span>, fFrame);
    }
    fEditor.showDialog();
  }
  
  <span class='comment'>// PRIVATE //
</span>  <span class='keyword'>private</span> JFrame fFrame;
  <span class='keyword'>private</span> java.util.List&lt;PreferencesEditor&gt; fPrefEditors;
  <span class='keyword'>private</span> <span class='keyword'>static</span> <span class='keyword'>final</span> Logger fLogger = Util.getLogger(EditUserPreferencesAction.<span class='keyword'>class</span>);  
  
  <span class='comment'>/**
  * Specifying this as a field allows for "lazy" creation and use of the GUI, which is 
  * of particular importance for a preferences dialog, since they are usually heavyweight, 
  * and have a large number of components.
  */</span>
  <span class='keyword'>private</span> Editor fEditor;
  
  <span class='comment'>/**
  * Return GUI for editing all preferences, pre-populated with current 
  * values.
  */</span>
  <span class='keyword'>private</span> JComponent getPrefEditors(){
    JTabbedPane content = <span class='keyword'>new</span> JTabbedPane();
    content.setTabPlacement(JTabbedPane.LEFT);
    <span class='keyword'>int</span> idx = <span class='literal'>0</span>;
    <span class='keyword'>for</span>(PreferencesEditor prefEditor: fPrefEditors) {
      JComponent editorGui = prefEditor.getUI();
      editorGui.setBorder(UiUtil.getStandardBorder());
      content.addTab(prefEditor.getTitle() , editorGui);
      content.setMnemonicAt(idx, prefEditor.getMnemonic());
      ++idx;
    }
    <span class='keyword'>return</span> content;
  }
  
  <span class='comment'>/** Called only when the user hits the OK button.  */</span>
  <span class='keyword'>private</span> <span class='keyword'>void</span> saveSettings(){
    fLogger.fine(<span class='literal'>"User selected OK. Updating table preferences."</span>);
    <span class='keyword'>for</span>(PreferencesEditor prefEditor: fPrefEditors) {
      prefEditor.savePreferences();
    }
  }
  
  <span class='comment'>/**
  * An example of a nested class which is nested because it is attached only 
  * to the enclosing class, and it cannot act as superclass since multiple 
  * inheritance of implementation is not possible. 
  * 
  * The implementation of this nested class is kept short by calling methods 
  * of the enclosing class.
  */</span>
  <span class='keyword'>private</span> <span class='keyword'>final</span> <span class='keyword'>class</span> Editor <span class='keyword'>extends</span> StandardEditor { 
    
    Editor(String aTitle, JFrame aParent){
      <span class='keyword'>super</span>(aTitle, aParent, StandardEditor.CloseAction.HIDE);
    }

    <span class='keyword'>public</span> JComponent getEditorUI () {
      JPanel content = <span class='keyword'>new</span> JPanel();
      content.setLayout( <span class='keyword'>new</span> BoxLayout(content, BoxLayout.Y_AXIS) );
      content.add( getPrefEditors() );
      <span class='comment'>//content.setMinimumSize(new Dimension(300,300) );
</span>      <span class='keyword'>return</span> content;
    }
    
    <span class='keyword'>public</span> <span class='keyword'>void</span> okAction() {
      saveSettings();
      dispose();
    }
  }  
}
 
</PRE>
<br>
<br>
<br>

</div>




<div class='topic-section'>See Also :</div>
<div class='main-body'>
 
  
  <a href='TopicAction19ff-2.html?Id=11'>Constructors in general</a> <br>
 
  
  <a href='TopicAction78db-2.html?Id=28'>Implementing hashCode</a> <br>
 
  
  <a href='TopicAction3d35-2.html?Id=92'>Self-encapsulate fields</a> <br>
 
  
  <a href='TopicAction7910-2.html?Id=150'>Standardized dialogs</a> <br>
 
</div>


<div class='topic-section'>Would you use this technique?</div>
<div class='main-body'>
  
  <form action="http://www.javapractices.com/vote/AddVoteAction.do" method='post'>
    Yes<input type='radio' name='Choice' value='Y' >
    &nbsp;&nbsp;No<input type='radio' name='Choice' value='N'>
    &nbsp;&nbsp;Undecided<input type='radio' name='Choice' value="?" >
    &nbsp;&nbsp;<input type=submit value="Vote" >
    <input type='hidden' name='Operation' value='Apply'>
    <input type='hidden' name='TopicId' value='34'>
  </form>
</div>

<div style='height:10.0em;'></div>

 
 
</div>

  

 





<div align='center' class='legalese'>  
&copy; 2011 Hirondelle Systems |
<a href='../source/SourceAction-2.html'><b>Source Code</b></a><IMG class='no-margin' SRC="../images/goldstar.gif" ALT=""> |
<a href="mailto:webmaster@javapractices.com">Contact</a> |
<a href="http://creativecommons.org/licenses/by-nc-sa/1.0/">License</a> |
<a href='../apps/cjp.rss'>RSS</a>
<!-- ukey="2AC36CD2" -->
<!-- ckey="16DF3D87" -->
<br>

 Individual code snippets can be used under this <a href='../LICENSE.txt'>BSD license</a> - Last updated on June 6, 2010.<br>
 Over 150,000 unique IPs last month - <span title='Java Practices 2.6.5, Mon May 16 00:00:00 EDT 2011'>Built with</span> <a href='http://www.web4j.com/'>WEB4J</a>.<br>
 - In Memoriam : Bill Dirani -
</div>

<script src="../../www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-2633428-1";
urchinTracker();
</script>



</body>

<!-- Mirrored from www.javapractices.com/topic/TopicAction.do?Id=34 by HTTrack Website Copier/3.x [XR&CO'2010], Sun, 12 Jun 2011 17:28:07 GMT -->
<!-- Added by HTTrack --><meta http-equiv="content-type" content="text/html;charset=UTF-8"><!-- /Added by HTTrack -->
</html>
